package com.mmz.spring.aop.framework;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

import org.aopalliance.intercept.MethodInvocation;

import com.mmz.spring.aop.TargetSource;



public class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable{

	private final AdvisedSupport advised;

	private boolean equalsDefined;

	private boolean hashCodeDefined;
	
	
	public JdkDynamicAopProxy(AdvisedSupport config){
		
		if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
			throw new RuntimeException("No advisors and no TargetSource specified");
		}
		this.advised = config;
	}
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		Object oldProxy = null;
		boolean setProxyContext = false;

		TargetSource targetSource = this.advised.targetSource;
		Class<?> targetClass = null;
		Object target = null;

		
			
			target = targetSource.getTarget();
			if (target != null) {
				targetClass = target.getClass();
			}

			Object retVal = null;
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			if (chain.isEmpty()) {
				
				retVal = method.invoke(target, args);
			}
			else {
				
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				
				retVal = invocation.proceed();
			}

			
			
			return retVal;
	}

	public Object getProxy() {
		
		return getProxy(Thread.currentThread().getContextClassLoader());
	}

	/**
	 * 真正生成代理对象，本质上还是使用的jdk动态代理
	 * */
	public Object getProxy(ClassLoader classLoader) {
		// TODO Auto-generated method stub
		return Proxy.newProxyInstance(classLoader, this.advised.getProxiedInterfaces(), this);
	}

}
